package com.laughing.lib

import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.ViewModel
import com.cf.holder.BaseHolder
import com.laughing.lib.base.HBaseViewModel
import com.laughing.lib.base.getVm
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.ParameterizedType

fun <V : HBaseViewModel> Fragment.bindViewModel(aClass: Class<*>): V {
    try {
        val actualTypeArguments =
            (aClass.genericSuperclass as? ParameterizedType)?.actualTypeArguments
        if (actualTypeArguments != null) {
            for (i in actualTypeArguments.indices) {
                val tClass: Class<Any>
                try {
                    tClass = actualTypeArguments[i] as Class<Any>
                } catch (e: Exception) {
                    continue
                }
                if (ViewModel::class.java.isAssignableFrom(tClass)) {
                    val clz: Class<HBaseViewModel> = tClass as Class<HBaseViewModel>
                    return getVm(this, clz) as V
                }
            }
        }
        return this.bindViewModel(aClass.superclass)
    } catch (e: NoSuchMethodException) {
        e.printStackTrace()
    } catch (e: IllegalAccessException) {
        e.printStackTrace()
    } catch (e: InvocationTargetException) {
        e.printStackTrace()
    }
    throw RuntimeException("ViewBinding初始化失败")
}

fun <V : HBaseViewModel> FragmentActivity.bindViewModel(aClass: Class<*>): V {
    try {
        val actualTypeArguments =
            (aClass.genericSuperclass as? ParameterizedType)?.actualTypeArguments
        if (actualTypeArguments != null) {
            for (i in actualTypeArguments.indices) {
                val tClass: Class<Any>
                try {
                    tClass = actualTypeArguments[i] as Class<Any>
                } catch (e: Exception) {
                    continue
                }
                if (ViewModel::class.java.isAssignableFrom(tClass)) {
                    val clz: Class<HBaseViewModel> = tClass as Class<HBaseViewModel>
                    return getVm(this, clz) as V
                }
            }
        }
        return this.bindViewModel(aClass.superclass)
    } catch (e: NoSuchMethodException) {
        e.printStackTrace()
    } catch (e: IllegalAccessException) {
        e.printStackTrace()
    } catch (e: InvocationTargetException) {
        e.printStackTrace()
    }
    throw RuntimeException("ViewBinding初始化失败")
}

fun <V : HBaseViewModel> BaseHolder<*>.bindViewModel(aClass: Class<*>): V {
    try {
        val actualTypeArguments =
            (aClass.genericSuperclass as? ParameterizedType)?.actualTypeArguments
        if (actualTypeArguments != null) {
            for (i in actualTypeArguments.indices) {
                val tClass: Class<Any>
                try {
                    tClass = actualTypeArguments[i] as Class<Any>
                } catch (e: Exception) {
                    continue
                }
                if (ViewModel::class.java.isAssignableFrom(tClass)) {
                    val clz: Class<HBaseViewModel> = tClass as Class<HBaseViewModel>
                    return getVm(this, clz) as V
                }
            }
        }
        return this.bindViewModel(aClass.superclass)
    } catch (e: NoSuchMethodException) {
        e.printStackTrace()
    } catch (e: IllegalAccessException) {
        e.printStackTrace()
    } catch (e: InvocationTargetException) {
        e.printStackTrace()
    }
    throw RuntimeException("ViewBinding初始化失败")
}